package cn.fangline.wo.task.akka.actors;

import akka.actor.AbstractActor;
import akka.actor.Actor;
import akka.actor.ActorRef;
import cn.fangline.base.util.StringUtil;
import cn.fangline.wo.model.OriginHouse;
import cn.fangline.wo.task.akka.messages.CheckAlive;
import cn.fangline.wo.task.akka.messages.EndPoint;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.sun.tools.corba.se.idl.constExpr.Or;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.stream.Collectors;

/**
 * Created by 抽离 on 2017/6/27 0027.
 */
public class HouseExistActor extends AbstractActor {

    private boolean isAlive = true;

    private ActorRef houseInsertRef;

    private ActorRef houseUpdateRef;

    public HouseExistActor(ActorRef houseInsertRef, ActorRef houseUpdateRef) {
        this.houseInsertRef = houseInsertRef;
        this.houseUpdateRef = houseUpdateRef;
    }

    @Override
    public Receive createReceive() {
        return
                 receiveBuilder()
                        .match(List.class, this::onReceiveOriginHouseList)
                         .match(CheckAlive.class, this::onReceiveCheckAlive)
                         .match(EndPoint.class, this::onReceiveEndPoint)
                        .build();
    }

    private  void onReceiveEndPoint(EndPoint m) {
        isAlive = true;
    }

    private void onReceiveCheckAlive(Object m) {
        if(isAlive) {
            getSender().tell(true, getSelf());
            isAlive = false;
        }else{
            getSender().tell(false, getSelf());
        }
    }

    private void onReceiveOriginHouseList(List<OriginHouse> originHouses) {
//        System.out.println("获取到originHouse列表：" + originHouses);
        OriginHouse originHouse = new OriginHouse();
        Map<String, OriginHouse> map = originHouse.selectList(
                new EntityWrapper<OriginHouse>().in("origin_house_id",
                originHouses
                .stream()
                .map(OriginHouse::getOriginHouseId)
                .collect(Collectors.toList())))
                .stream()
                .reduce(
                        new HashMap<String, OriginHouse>(),
                        new BiFunction<HashMap<String, OriginHouse>, OriginHouse, HashMap<String, OriginHouse>>() {
                            @Override
                            public HashMap<String, OriginHouse> apply(HashMap<String, OriginHouse> stringOriginHouseHashMap, OriginHouse originHouse) {
                                stringOriginHouseHashMap.put(originHouse.getOriginHouseId(), originHouse);
                                return stringOriginHouseHashMap;
                            }
                        },
                        new BinaryOperator<HashMap<String, OriginHouse>>() {
                            @Override
                            public HashMap<String, OriginHouse> apply(HashMap<String, OriginHouse> stringOriginHouseHashMap, HashMap<String, OriginHouse> stringOriginHouseHashMap2) {
                                stringOriginHouseHashMap.putAll(stringOriginHouseHashMap2);
                                return stringOriginHouseHashMap;
                            }
                        }
                );

        List<List<OriginHouse>> result = originHouses
                .stream()
                .reduce(
                        new ArrayList<List<OriginHouse>>() {{
                            add(new ArrayList<OriginHouse>());//第1个list存储数据库不存在的需要insert的originHouse
                            add(new ArrayList<OriginHouse>());//第二个list存储数据库存在但是需要更新的originHouse
                            add(new ArrayList<OriginHouse>());//第3个存放数据库已有而且不需要更新的originHouse
                        }},
                        new BiFunction<ArrayList<List<OriginHouse>>, OriginHouse, ArrayList<List<OriginHouse>>>() {
                            @Override
                            public ArrayList<List<OriginHouse>> apply(ArrayList<List<OriginHouse>> lists, OriginHouse oh) {
                                if(oh.getTotalPrice() == null){
                                    lists.get(2).add(oh);
                                    return lists;
                                }
                                if(map.containsKey(oh.getOriginHouseId())){
                                    OriginHouse h = map.get(oh.getOriginHouseId());
                                    if(!oh.getTotalPrice().equals(h.getTotalPrice())){
                                        h.setTotalPrice(oh.getTotalPrice());
                                        lists.get(1).add(h);
                                    }
                                    return  lists;
                                }
                                lists.get(0).add(oh);
                                return lists;
                            }
                        },
                        new BinaryOperator<ArrayList<List<OriginHouse>>>() {
                            @Override
                            public ArrayList<List<OriginHouse>> apply(ArrayList<List<OriginHouse>> lists, ArrayList<List<OriginHouse>> lists2) {
                                lists.get(0).addAll(lists2.get(0));
                                lists.get(1).addAll(lists2.get(1));
                                lists.get(2).addAll(lists2.get(2));
                                return lists;
                            }
                        }
                );


        houseInsertRef.tell(result.get(0), getSelf());

        houseUpdateRef.tell(result.get(1), getSelf());
    }
}
